package pomodorotasks

import griffon.core.GriffonApplication
import griffon.test.GriffonUnitTestCase

import com.google.api.client.util.DateTime

import com.google.api.services.tasks.model.Task
import com.google.api.services.tasks.model.Tasks
import com.google.api.services.tasks.model.TaskList

import pomodorotasks.testutils.ThreadingUtils
import pomodorotasks.testutils.PomodoroApplicationFacade
import pomodorotasks.testutils.GoogleTasksUtils
import pomodorotasks.testutils.JTableUtils

class PomodoroTasksListTests extends GriffonUnitTestCase {
    GriffonApplication app
    
    PomodoroApplicationFacade pomodoroApp
    
    def googleAppServiceMock
    def view
    def controller
    def model
    
    def taskListName = 'TaskList'
    
    public static int FIRST_ROW_INDEX = 0
    
    public static String COMPLETED_STATUS = 'completed'
    
    public static String NEEDS_ACTION_STATUS = 'needsAction'

    protected void setUp() {
        super.setUp()
        pomodoroApp = new PomodoroApplicationFacade(app, this)
        googleAppServiceMock = pomodoroApp.mockGoogleTasksService()
        
        pomodoroApp.startApp()
    }
    
    private Tasks displayAndReturnTasks(List tasksList) {
        
        def taskLists = pomodoroApp.addTaskLists([taskListName])
        
        def taskList = taskLists.items[0]
        Tasks tasks = new Tasks(items: tasksList)
        googleAppServiceMock.demand.getTasks {TaskList list -> tasks}
        
        pomodoroApp.selectTaskList(taskListName)
        Thread.sleep(5000)
        return tasks
    }

    protected void tearDown() {
        super.tearDown()
        pomodoroApp.clean()
    }
    
    void assertRowRepresentsTask(tasksTable, index, task) {
        boolean status = false
        if (task.status == NEEDS_ACTION_STATUS) {
            status = false
        } else if (task.status == COMPLETED_STATUS) {
            status = true
        } else {
            assert false : "Invalid task status: $task.status"
        }
        JTableUtils.assertValueAt(tasksTable, 'Status', index, status)
        JTableUtils.assertValueAt(tasksTable, 'Title', index, task.title)
        JTableUtils.assertValueAt(tasksTable, 'Updated', index, task.updated)
    }
    
    void assertRowsRepresentTasks(tasksTable, tasks) {
        assertEquals(tasks.size(), tasksTable.getRowCount())
        tasks.eachWithIndex {task, index -> assertRowRepresentsTask(tasksTable, index, task)}
    }

    void testDisplayOneTask() {
        DateTime updateDate = new DateTime(new Date())
        Task task1 = new Task(title: 'Task1', 
            status: NEEDS_ACTION_STATUS, 
            updated: updateDate)
        def tasksList = [task1]
        displayAndReturnTasks(tasksList)
        def view = pomodoroApp.getPomodoroTasksListView(taskListName)
        def tasksTable = view.tasksTable
        assertRowsRepresentTasks(tasksTable, tasksList)
    }
    
    void testDisplayTwoTask() {
        DateTime updateDate = new DateTime(new Date())
        Task task1 = new Task(title: 'Task1', 
            status: NEEDS_ACTION_STATUS, 
            updated: updateDate)
        Task task2 = new Task(title: 'Task2', 
            status: COMPLETED_STATUS, 
            updated: updateDate)
        def tasksList = [task1, task2]
        displayAndReturnTasks(tasksList)
        def view = pomodoroApp.getPomodoroTasksListView(taskListName)
        def tasksTable = view.tasksTable
        assertRowsRepresentTasks(tasksTable, tasksList)
    }
    
    void testUpdateStatus() {
        DateTime updateDate = new DateTime(new Date())
        Task task1 = new Task(title: 'Task1', 
            status: NEEDS_ACTION_STATUS, 
            updated: updateDate)
        def tasksList = [task1]
        def tasks = displayAndReturnTasks(tasksList)
        def view = pomodoroApp.getPomodoroTasksListView(taskListName)
        def tasksTable = view.tasksTable
        assertRowsRepresentTasks(tasksTable, tasksList)
        googleAppServiceMock.demand.updateTask {TaskList taskList, Task task -> 
            assert task == task1 
            return task
        }
        googleAppServiceMock.demand.getTasks {TaskList list -> tasks}
        execSync {
            tasksTable.setValueAt(true, FIRST_ROW_INDEX, JTableUtils.getColumnFromName(tasksTable, 'Status'))
        }
        ThreadingUtils.waitForAsyncOperationsComplete()
        assert task1.status == COMPLETED_STATUS
    }
    
}
